package com.service.business.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.service.business.base.service.ConfigService;
import com.service.business.member.dto.MemberStoreChange;
import com.service.business.member.service.*;
import com.service.business.order.service.OrderProductHrComboDetailsService;
import com.service.business.order.service.OrderProductHrComboService;
import com.service.business.product.service.ProductHrComboService;
import com.service.business.support.MemberStoreLockUtils;
import com.service.dao.enums.HashRateOrderEnums;
import com.service.dao.enums.MemberJAType;
import com.service.dao.model.*;
import com.service.dao.po.MemberCache;
import com.service.utility.common.MathUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

@Slf4j
@Service
public class MemberAwardByHrComboOrderServiceImpl implements MemberAwardByHrComboOrderService {

	@Autowired
	private ConfigService configService;
	@Autowired
	private MemberService memberService;
	@Autowired
	private MemberCacheService memberCacheService;
	@Autowired
	private MemberGradeConfigService gradeConfigService;
	@Autowired
	private OrderProductHrComboService orderProductHrComboService;
	@Autowired
	private OrderProductHrComboDetailsService detailsService;
	@Autowired
	private MemberStoreService storeService;
	@Autowired
	private MemberStoreLockUtils memberStoreLockUtils;
	@Autowired
	private ProductHrComboService productHrComboService;

	private final BigDecimal ONE_HUNDRED = BigDecimal.valueOf(100.00);

	private final int AWARDCOMBONUM = 1;

	/**
	 * 发送直推算力奖励
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sendMemberDRHashRate(OrderProductHrCombo orderProductHrCombo, Integer memberId) {
		if (ObjectUtils.isEmpty(memberId)) {
			log.info("会员<memberId:{}>购买发放直推奖结束，无父级", orderProductHrCombo.getMemberId());
			return;
		}
		Member buyMember = memberService.getMemberById(orderProductHrCombo.getMemberId());
		Member pMember = memberService.getMemberById(memberId);
		if (ObjectUtils.isEmpty(pMember)) {
			log.info("会员<memberId:{}>购买发放直推奖结束，无父级", orderProductHrCombo.getMemberId());
			return;
		}
		//获取直推用户vip等级对应的直推奖励比例
		MemberGradeConfig gradeConfig = gradeConfigService.getOne(new QueryWrapper<MemberGradeConfig>().lambda()
				.eq(MemberGradeConfig::getId, pMember.getVipGrade())
		);
		BigDecimal rate = MathUtil.div(gradeConfig.getDirectRewardRate(), ONE_HUNDRED, 4);
		BigDecimal reward = MathUtil.mul(orderProductHrCombo.getOrderMoney(), rate);
		if (reward.compareTo(BigDecimal.ZERO) <= 0) {
			return;
		}
		//获取父级用户账户
		OrderProductHrComboDetails details = detailsService.getOne(new QueryWrapper<OrderProductHrComboDetails>().lambda()
				.eq(OrderProductHrComboDetails::getHrOrderId, orderProductHrCombo.getId())
		);
		ProductHrCombo combo = productHrComboService.getById(details.getComboId());
		MemberStore memberStore = storeService.getMemberStore(pMember.getId(), combo.getFromCoinsName());
		boolean isLock = memberStoreLockUtils.lock(pMember.getId(), memberStore.getId());
		if (isLock) {
			try {
				MemberStoreChange storeChange = MemberStoreChange.builder()
						.memberId(pMember.getId())
						.changeNum(reward)
						.coinsId(combo.getFromCoinsId())
						.coinsName(combo.getFromCoinsName())
						.orderId(orderProductHrCombo.getId())
						.orderDetailId(details.getId())
						.jaType(MemberJAType.RECOMMEND_11)
						.remark(buyMember.getUserAccount() + "->" + pMember.getUserAccount() + MemberJAType.RECOMMEND_11.getMsg())
						.build();
				storeService.changeMemberStore(storeChange);
			} finally {
				memberStoreLockUtils.unlock(pMember.getId(), memberStore.getId());
			}
		}
		log.info("会员<memberId:{}>购买算力发放直推奖:{} {}", orderProductHrCombo.getMemberId(), reward, combo.getFromCoinsName());
	}

	/**
	 * 发送间推算力奖励
	 */
//	@Override
//	@Transactional(rollbackFor = Exception.class)
//	public void sendMemberIRHashRate(OrderProductHrCombo orderProductHrCombo, Integer memberId) {
//		if (ObjectUtils.isEmpty(memberId)) {
//			log.info("会员<memberId:{}>购买算力发放间推奖结束，无祖父级", orderProductHrCombo.getMemberId());
//			return;
//		}
//		Member buyMember = memberService.getMemberById(orderProductHrCombo.getMemberId());
//		Member gMember = memberService.getMemberById(memberId);
//		if (ObjectUtils.isEmpty(gMember)) {
//			log.info("会员<memberId:{}>购买算力发放间推奖结束，无祖父级", orderProductHrCombo.getMemberId());
//			return;
//		}
//		//获取间推用户vip等级对应的直推奖励比例
//		MemberGradeConfig gradeConfig = gradeConfigService.getOne(new QueryWrapper<MemberGradeConfig>().lambda()
//				.eq(MemberGradeConfig::getId, gMember.getVipGrade())
//		);
//		BigDecimal rate = MathUtil.div(gradeConfig.getIndirectRecommendationRate(), ONE_HUNDRED, 4);
//		BigDecimal reward = MathUtil.mul(orderProductHrCombo.getProductPv(), rate);
//		if (reward.compareTo(BigDecimal.ZERO) <= 0) {
//			return;
//		}
//		//获取祖父级用户账户
//		OrderProductHrComboDetails details = detailsService.getOne(new QueryWrapper<OrderProductHrComboDetails>().lambda()
//				.eq(OrderProductHrComboDetails::getHrOrderId, orderProductHrCombo.getId())
//		);
//		ProductHrCombo combo = productHrComboService.getById(details.getComboId());
//		MemberStore memberStore = storeService.getMemberStore(gMember.getId(), combo.getFromCoinsName());
//		boolean isLock = memberStoreLockUtils.lock(gMember.getId(), memberStore.getId());
//		if (isLock) {
//			try {
//				MemberStoreChange storeChange = MemberStoreChange.builder()
//						.memberId(gMember.getId())
//						.changeNum(reward)
//						.coinsId(combo.getFromCoinsId())
//						.coinsName(combo.getFromCoinsName())
//						.orderId(orderProductHrCombo.getId())
//						.orderDetailId(details.getId())
//						.jaType(MemberJAType.RECOMMEND_12)
//						.remark(buyMember.getMobile()+"->"+MemberJAType.RECOMMEND_12.getMsg())
//						.build();
//				storeService.changeMemberStore(storeChange);
//			} finally {
//				memberStoreLockUtils.unlock(gMember.getId(), memberStore.getId());
//			}
//		}
//		log.info("会员<memberId:{}>购买算力发放间推奖:{} {}", orderProductHrCombo.getMemberId(), reward, combo.getFromCoinsName());
//	}

	/**
	 * 发放团队算力奖励
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sendMemberTeamHashRate(OrderProductHrCombo orderProductHrCombo, Member orderMember) {
		if (StringUtils.isBlank(orderMember.getUserPath())) {
			return;
		}
		log.info("会员<{}>推荐路径:{}", orderMember.getId(), orderMember.getUserPath());
		Map<Integer, MemberGradeConfig> gradeConfigMap = gradeConfigService.list2Map();
		List<Integer> memberPath = getReverseMemberPath(orderMember.getUserPath());

		OrderProductHrComboDetails comboDetails = detailsService.updateHrComboInterval(orderProductHrCombo.getId());
		AtomicReference<BigDecimal> lastAwardRate = new AtomicReference<>(BigDecimal.ZERO);

		memberPath.forEach(item -> {
			Member member = memberService.getMemberById(item);
			if (ObjectUtils.isEmpty(member)) {
				log.info("会员<{}>上级<{}>已删除，团队算力奖励跳过", orderMember.getId(), item);
				return;
			}
			MemberCache memberCache = memberCacheService.getMemberCache(item);
			Integer memberGradeVip = memberCache.getMemberGrade();
			memberService.checkAndUpdateMemberGrade(memberCache);
			MemberGradeConfig gradeConfig = gradeConfigMap.get(memberGradeVip);
			if (!isMoreThenZero(gradeConfig.getTeamMemberRate())) {
				log.info("会员<{}:grade:{}>上级<{}:{}> 团队极差算力奖励比例为0", orderMember.getId(), orderMember.getVipGrade(), member.getId(), memberGradeVip);
				return;
			}
			log.info("会员<{}:grade:{}>上级<{}:{}> 上一个会员团队极差算力奖励比例为:{},当前会员团队极差算力奖励比例:{}",
					orderMember.getId(), orderMember.getVipGrade(), member.getId(), memberGradeVip, lastAwardRate.get(), gradeConfig.getTeamMemberRate());

			BigDecimal rate = gradeConfig.getTeamMemberRate().subtract(lastAwardRate.getAndSet(gradeConfig.getTeamMemberRate()));
			if (!isMoreThenZero(rate)) {
				log.info("会员<{}:grade:{}>上级<{}:{}> 团队极差算力奖励比例为0",
						orderMember.getId(), orderMember.getVipGrade(), member.getId(), memberGradeVip);
				return;
			}
			rate = MathUtil.div(rate, ONE_HUNDRED, 4);
			BigDecimal hrNum = orderProductHrCombo.getOrderMoney().multiply(rate);

			log.info("会员<{}:grade:{}>上级<{}:{}> 订单算力:{}, 团队极差算力奖励比例:{} 奖励算力:{}",
					orderMember.getId(), orderMember.getVipGrade(), member.getId(),
					memberGradeVip, orderProductHrCombo.getTotalHashRate(), rate, hrNum);

			boolean isLock = memberStoreLockUtils.lock(item, comboDetails.getFromCoinsId());
			if (!isLock) {
				return;
			}
			try{
				storeService.changeMemberStore(
						MemberStoreChange.builder()
								.memberId(item)
								.coinsId(comboDetails.getFromCoinsId())
								.coinsName(comboDetails.getFromCoinsName())
								.jaType(MemberJAType.PERFORMANCE_REWARD)
								.orderId(orderProductHrCombo.getId())
								.custodyFee(BigDecimal.ZERO)
								.orderDetailId(comboDetails.getId())
								.changeNum(hrNum)
								.remark(MemberJAType.PERFORMANCE_REWARD.getMsg().toString())
								.build());
			}finally {
				memberStoreLockUtils.unlock(item, comboDetails.getFromCoinsId());
			}
		});
	}

	private boolean isMoreThenZero(BigDecimal num) {
		return num.compareTo(BigDecimal.ZERO) > 0;
	}

	public List<Integer> getReverseMemberPath(String memberPath) {
		return Lists.reverse(memberService.getMemberPathList(memberPath));
	}

}
